package cn.itcast.protocol;

import cn.itcast.config.Config;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;
import lombok.extern.slf4j.Slf4j;
import cn.itcast.message.Message;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;

/**
 * 必须和 LengthFieldBasedFrameDecoder 一起使用，确保接到的 ByteBuf 消息是完整的
 */
@Slf4j
@ChannelHandler.Sharable
public class MessageCodec extends MessageToMessageCodec<ByteBuf, Message> {
    int serializerAlgorithm = Config.getSerializerAlgorithm().ordinal();

    @Override
    protected void encode(ChannelHandlerContext ctx, Message msg, List<Object> outList) throws Exception {
        ByteBuf out = ctx.alloc().buffer();
//        ByteBuf out = ByteBufAllocator.DEFAULT.buffer();
        // 4字节 魔数号
        out.writeBytes(new byte[]{1, 2, 3, 4});
        // 1字节 版本号
        out.writeByte(1);
        // 1字节 序列化方式 jdk 0 ;json 1;
        out.writeByte(serializerAlgorithm);
        // 1字节 指令类型
        log.debug("MessageType {} ", msg.getMessageType());
        out.writeByte(msg.getMessageType());
        // 4字节 指令请求序号
        out.writeInt(msg.getSequenceId());
        // 对齐填充使用
        out.writeByte(0xff);
        // 获取内容的字节数组

        // 序列化
//        ByteArrayOutputStream bos = new ByteArrayOutputStream();
//        ObjectOutputStream oos = new ObjectOutputStream(bos);
//        oos.writeObject(msg);
//        // 获取序列化后的数据
//        byte[] bytes = bos.toByteArray();

        byte[] bytes = Serializer.Algorithm.values()[serializerAlgorithm].serialize(msg);

        // 4字节 长度
        out.writeInt(bytes.length);
        // 写入内容
        out.writeBytes(bytes);

        outList.add(out);
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> outList) throws Exception {
        // 4字节 魔数号
        int magicNum = msg.readInt();
        // 1字节 版本号
        byte version = msg.readByte();
        // 1字节 序列化方式 jdk 0 ;json 1;
        byte serializerAlgorithm = msg.readByte();
        // 1字节 指令类型
        byte messageType = msg.readByte();
        // 4字节 指令请求序号
        int sequenceId = msg.readInt();
        // 对齐填充使用
        msg.readByte();
        // 4字节 长度
        int length = msg.readInt();
        // n字节 正文
        byte[] bytes = new byte[length];
        msg.readBytes(bytes, 0, length);

        // 如果序列化方式为 jdk
//        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
//        Message message = (Message) ois.readObject();

        Serializer.Algorithm algorithm = Serializer.Algorithm.values()[serializerAlgorithm];
        Class<?> messageClass = Message.getMessageClass(messageType);
        Object message = algorithm.deserialize(messageClass, bytes);

        outList.add(message);
    }
}




















